package com.lucker.common.util;


import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cglib.beans.BeanCopier;


/**********************************************
 * <p>
 * 说明：map工具类
 * </p>
 * 
 * @author liujinlei
 * @date 2015年7月16日 上午9:16:32
 * @version 2.0.1 <br/>
 **********************************************
 */
public class MapUtils extends org.apache.commons.collections.MapUtils{
	
	/**********************************************
	 * 
	 * @author zyf
	 * @date 2016.10.22
	 * return : 返回map 集合中 key 所有 key 的字符串 ， 用逗号分割
	 */
	public static String getMapKeysArrayString(Map<String,Object> map){
		if(MapUtils.isEmpty(map)){
			return null;
		}else{
			String ret = "";
			for (String key : map.keySet()) {
				  ret = ret + key + "," ;
			}
			if(!StringUtils.isBlank(ret)){
				
				ret = StringUtils.substring(ret, 0, ret.length() - 1);
			}
			return ret;
		}
	}

	/**********************************************
	 * 
	 * @author zyf
	 * @date 2016.10.22
	 * return : 返回map 集合中 key 所有 value 的字符串 ， 用逗号分割
	 */
	public static String getMapValuesArrayString(Map<String,Object> map){
		if(MapUtils.isEmpty(map)){
			return null;
		}else{
			String ret = "";
			for (String key : map.keySet()) {
				 if(map.get(key) instanceof Number){
					 ret = ret  + map.get(key) +   "," ;
				 }else{
					 ret = ret  + "'" + map.get(key) +   "'," ;
				 }
			}
			if(!StringUtils.isBlank(ret)){
				ret = StringUtils.substring(ret, 0, ret.length() - 1);
			}
			return ret;
		}
	}
	
	/**********************************************************
	 * 将集合中的KEY,VALUE封装成HTTP请求的 参数字符串 如：a=1&b=2&c=zyf
	 * @author zyf
	 * @date 2016.12.21
	 */
	public static  String getUrlParamsByMap(Map<String, Object> map) {  
	    if (map == null) {  
	        return "";  
	    }  
	    StringBuffer sb = new StringBuffer();  
	    for (Map.Entry<String, Object> entry : map.entrySet()) {  
	        sb.append(entry.getKey() + "=" + entry.getValue());  
	        sb.append("&");  
	    }  
	    String s = sb.toString();  
	    if (s.endsWith("&")) {  
	        s = org.apache.commons.lang.StringUtils.substringBeforeLast(s, "&");  
	    }  
	    return s;  
	}
	
//	
//	public static Map sortMapByKey(Map map) {  
//        Map<Object, Object> mapVK = new TreeMap<Object, Object>(  
//                new Comparator<Object>() {  
//                    public int compare(Object obj1, Object obj2) {  
//                        String v1 = (String) obj1;  
//                        String v2 = (String) obj2;  
//                        int s = v2.compareTo(v1);  
//                        return s;  
//                    }  
//                });  
//        Set col = map.keySet();  
//        Iterator iter = col.iterator();  
//        while (iter.hasNext()) {  
//            String key = (String) iter.next();  
//            Integer value = (Integer) map.get(key);  
//            mapVK.put(key, value);  
//        }  
//        
//        return mapVK;  
//    }  

//	public static void sortMapByKey(Map<String,Object> map) {
//		
//		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(map.entrySet()); 
//		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
//	            public int compare(Map.Entry<String, Object> o1,  
//	                    Map.Entry<String, Object> o2) {  
//	                return (o1.getKey()).toString().compareTo(o2.getKey().toString());  
//	            }  
//	    });  
//		
//		for (String key : map.keySet()) {
//            System.out.println("key= "+ key + "  value= " + map.get(key));
//        }
//	}
	
	
    public static void sortMapByValue(Map maps) {  
        List<Map.Entry<String, Integer>> info = new ArrayList<Map.Entry<String, Integer>>(maps.entrySet());  
        Collections.sort(info, new Comparator<Map.Entry<String, Integer>>() {  
            public int compare(Map.Entry<String, Integer> obj1,Map.Entry<String, Integer> obj2) {  
                return obj2.getValue() - obj1.getValue();  
            }  
        });   
    }  
    
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {  
            return null;  
        }  
        Map<String, Object> sortMap = new TreeMap<String, Object>(new MapKeyComparator());  
        sortMap.putAll(map);  
        return sortMap;  
    }
    
    
    
    //
    
    public static Map<String,BeanCopier> beanCopierMap = new HashMap<String,BeanCopier>();
    
    public static void copy(Object source, Object target){
        String beanKey =  generateKey(source.getClass(), target.getClass());
        BeanCopier copier =  null;
        if(!beanCopierMap.containsKey(beanKey)){
             copier = BeanCopier.create(source.getClass(), target.getClass(), false);
             beanCopierMap.put(beanKey, copier);
        }else{
             copier = beanCopierMap.get(beanKey);
        }
        copier.copy(source, target, null);
    }   
    
    private static String generateKey(Class<?> class1,Class<?>class2){
        return class1.toString() + class2.toString();
    }
    
    
    public static Map<String, String> objectToMap(Object obj)  {      
        if(obj == null){      
            return null;      
        }     
        Map<String, String> map = new HashMap<String, String>();      
        Field[] declaredFields = obj.getClass().getDeclaredFields();      
        try {
        	for (Field field : declaredFields) {      
                field.setAccessible(true); 
                if(field.get(obj) != null) {
                	if(field.getType() == Date.class || field.getType() == Timestamp.class) {
                		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                		map.put(field.getName(), sdf.format(field.get(obj)));
                	}else {
                		map.put(field.getName(), String.valueOf(field.get(obj)));
                	}
                	
                }
            }
        } catch(Exception e) {
        	e.printStackTrace();
        }  
     
        return map;    
    }     
    
    
    public static Map<String,String> beanToMap(Object bean){
        try {
        	return BeanUtils.describe(bean);
        } catch(Exception e) {
        	e.printStackTrace();
        }
        return null;
    }  
    /** 
     * map 转化为 bean 
     * @param clazz 
     * @param map 
     * @return 
     */
    
    public static <T> T mapToBean(Map<String, Object> map, Class<T> class1) {  
        T bean = null;  
        try {  
            bean = class1.newInstance();  
            BeanUtils.populate(bean, map);  
        } catch (InstantiationException e) {  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        } catch (InvocationTargetException e) {  
            e.printStackTrace();  
        }  
        return bean;  
    } 
    
    
    
    /** 
     *  
     *  
     * Map转换层Bean，使用泛型免去了类型转换的麻烦。 
     * @param <T> 
     * @param map   
     * @param class1 
     * @return 
     */  
    public static <T> T map2Bean(Map<String, String> map, Class<T> class1) {  
        T bean = null;  
        try {  
        	if(map == null || map.isEmpty()) {
        		return bean;
        	}
        	
            bean = class1.newInstance(); 
            ConvertUtils.register(new DateConverter(), java.util.Date.class); 
            BeanUtils.populate(bean, map);  
        } catch (InstantiationException e) {  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        } catch (InvocationTargetException e) {  
            e.printStackTrace();  
        }  
        return bean;  
    }  
    
    
    public static <T> T map2Obj(Map<String,String> map,Class<T> clz) {
        if (map == null)           return null;  
        try {
        	T obj = clz.newInstance(); 
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());  
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
            for (PropertyDescriptor property : propertyDescriptors) { 
              Method setter = property.getWriteMethod();  
              if (setter != null) { 
                setter.invoke(obj, map.get(property.getName()));  
              } 
            } 
            return obj;
        }catch(Exception e) {
        	e.printStackTrace();
        }
        return null;
      }
    
    
    

}
